<?php
if (!defined('FosfoaSystem')) {
    exit(1);
}
import($GLOBALS['spConfig']['controller_path'] . '/general.php');
/**
 * PAYPAL支付控制器
 * @author Fosf
 * @version 1.0
 * @created 2011-04-11
 */

class paypal extends general
{

    var $API_UserName = PAYPAL_EC_ACCOUNT;
    var $API_Password = PAYPAL_EC_SIGNATUREPASSWORD;
    var $API_Signature = PAYPAL_EC_SIGNATURE;
    var $API_Endpoint = PAYPAL_EC_API_HTTP;
    var $version = '65.1';
    var $subject = '';

    var $AUTH_token = '';
    var $AUTH_signature = '';
    var $AUTH_timestamp = '';
    
    var $SHIPPINGAMT=0;
    var $shippingselect;
    var $KD;
    function __construct()
    { // 公用
        parent::__construct(); // 这是必须的
        define('ACK_SUCCESS', 'SUCCESS');
        define('ACK_SUCCESS_WITH_WARNING', 'SUCCESSWITHWARNING');
        define('USE_PROXY', false);
        define('PROXY_HOST', '127.0.0.1');
        define('PROXY_PORT', '808');
        foreach ($this->shippingarr as $k => $v) {
                $KD .= '&L_SHIPPINGOPTIONAMOUNT' . $k . '=' . number_format($v[1] * $this->code2['value'], 2);
                $KD .= '&L_SHIPPINGOPTIONlABEL' . $k . '=' . $v[2];
                $KD .= '&L_SHIPPINGOPTIONNAME' . $k . '=' . $v[3];
                
                if (isset($_SESSION[shipping])) { //先判断用户是否选择快递运费
                    if ($_SESSION[shipping] == $v[0]) {
                        $shippingselect = $v; //运费相关
                        $SHIPPINGAMT = $v[1]; //运费，根据快递选择获得
                        $KD .= '&L_SHIPPINGOPTIONISDEFAULT' . $k . '=True';
                    }else{
                        $KD .= '&L_SHIPPINGOPTIONISDEFAULT' . $k . '=False';
                    }
                } else { //没有选择快递运费，就用默认运费
                    if (FREIGHT == $v[0]) {
                        $shippingselect = $v; //运费相关
                        $SHIPPINGAMT = $v[1]; //运费，根据快递选择获得
                        $KD .= '&L_SHIPPINGOPTIONISDEFAULT' . $k . '=True';
                    }else{
                        $KD .= '&L_SHIPPINGOPTIONISDEFAULT' . $k . '=False';
                    }
                }
            }
            $this->KD=$KD;
            $this->shippingselect=$shippingselect;
            $this->SHIPPINGAMT=$SHIPPINGAMT;
    }

    function clear_session()
    {
            unset($_SESSION['paypal_EC']);
            unset($_SESSION['reshash']);
            unset($_SESSION['payment_step']);
            unset($_SESSION['reshash_check']);
    }

    function paypalEC()
    {
        $type = $this->spArgs('type','create');
        $step = $this->spArgs('step');
        $token = $this->spArgs('token');
        $clearSess=$this->spArgs('clearSess');
        $ec_cancel=$this->spArgs('ec_cancel');
        $tourl=$this->spArgs('tourl');
        if (isset($clearSess) || isset($ec_cancel)) {

                $this->clear_session();
                $token ='';
        }
        if($step=='EC_payment'){
           $return=$this->DoExpressCheckoutPayment();
           if($return)
           $this->jump(spUrl('main','CheckoutSuccess')); 
        }
        
        if(isset($tourl))
        $this->jump($tourl.'.html');
        if($type=='EC_Final'){
        $paypal_step='&paypal_step=Order_Complete';
        }else{
            unset($_SESSION[shipping]);
            $_SESSION['payment_step']='checkout_payment';
        }
        
        if (!isset($token)) {
            $serverName = $_SERVER['SERVER_NAME'];
            $serverPort = $_SERVER['SERVER_PORT'];
            //$url = dirname('http://' . $serverName . ':' . $serverPort . $_SERVER['REQUEST_URI']); //获取网址http://127.0.0.1:80
            $url = WEBURL;

            $currencyCodeType = $this->code2[code]; //当前支付币种
            //dump($this->code2);
            $paymentType = PAYPAL_EC_PAYMENTTYPE;
            $status_id = PAYPAL_EC_ORDER_STATUS_ID;
            $payment = PAYPAL_EC_CODE;


            $KD=$this->KD;
            $shippingselect=$this->shippingselect;
            $SHIPPINGAMT=$this->SHIPPINGAMT;
            
            //dump($shippingselect);
            //echo $KD;
            //exit;
            if ($this->userarr['customers_id']) {
                $address = spClass('address_bookModel')->return_address($this->userarr['customers_default_address_id']);
                $address['SHIPTOCOUNTRYCODE'] = $this->forcount($address['entry_country_id'], 2);
                $address['entry_country_id'] = $this->forcount($address['entry_country_id']);
            }
            //dump($shippingselect);
            //exit;
            
            //创建订单
            if($type=='create')
            {spClass('orderModel')->create_order($status_id, $payment, $shippingselect,getIP(), $this->userarr, $address, $this->code2, $this->total, $Discount,$type);}
            
            
            //读取购物车内容
            $outArray = spClass('orderModel')->cartlist();
            
            //echo $_SESSION['orders_sn'];
            //echo $_SESSION['orders_id'];
            //dump($outArray);
            //exit;
            $productall = '';
            $itemamt = 0.00; //初始小计为0.00
            foreach ($outArray as $k => $v) {
                $productall .= 'L_NAME' . $k . '=' . $v[name] . '&'; //商品名
                $productall .= 'L_AMT' . $k . '=' . Get_price_abc(array('price'=>$v['price1']* $this->code2['value'],'price2'=>$v['price2']* $this->code2['value'])) . '&'; //单价


                $productall .= 'L_QTY' . $k . '=' . $v[count] . '&'; //数量
                //$L_NUMBER0=10001; //商品编号
                $productall .= 'L_DESC' . $k . '=' . $v[size] . '&'; //商品属性
                //$L_ITEMWEIGHTVALUE0=0.5;//重量
                //$L_ITEMWEIGHTUNIT0='lbs';//重量单位
                $itemamt += $v[Total]* $this->code2['value']; //计总价
            }
            //echo $productall;
            //echo $itemamt;
            //exit;
            $personName = $address['customers_firstname'] . ' ' . $address['customers_lastname']; //顾客姓名
            $SHIPTOSTREET = $address['entry_street_address']; //街道
            $SHIPTOCITY = $address['entry_city']; //城市
            $SHIPTOSTATE = $address['entry_state']; //省市
            $SHIPTOCOUNTRYCODE = $address['SHIPTOCOUNTRYCODE']; //国家代码US
            $SHIPTOZIP = $address['entry_postcode']; //邮编
            $CUSTOM = $_SESSION['orders_id']; //订单号ID
            $INVNUM = $_SESSION['orders_sn']; //订单号SN

            $returnURL = urlencode($url . spUrl('paypal','paypalEC'). "?currencyCodeType=$currencyCodeType&paymentType=$paymentType".$paypal_step);
            $cancelURL = urlencode($url . spUrl('paypal','paypalEC'). "?to=shopping_cart&ec_cancel=1");
            

            //$SHIPPINGAMT=8;//运费，根据快递选择获得
            $SHIPPINGAMT = number_format($SHIPPINGAMT, 2); //格式化保留2位小数，必须要有小数，不然PAYPAL报错
            $INSURANCEAMT = 0.00; //保险费
            $INSURANCEAMT = number_format($INSURANCEAMT, 2);
            $INSURANCEOPTIONOFFERED = 'False'; //True可选保险，False不可选强制保险
            if (isset($INSURANCEAMT))
                $shopping_about .= "INSURANCEAMT=$INSURANCEAMT&INSURANCEOPTIONOFFERED=$INSURANCEOPTIONOFFERED&";
            $SHIPDISCAMT = 0.00; //运费折扣
            $SHIPDISCAMT = number_format($SHIPDISCAMT, 2);
            if (isset($SHIPDISCAMT))
                $shopping_about .= "SHIPDISCAMT=$SHIPDISCAMT&";
            $TAXAMT = 0; //手续费税金
            $TAXAMT = number_format($TAXAMT, 2);
            if (isset($TAXAMT))
                $shopping_about .= "TAXAMT=$TAXAMT&";

            $amt = $SHIPPINGAMT + $TAXAMT + $INSURANCEAMT + $itemamt + $SHIPDISCAMT; //总金额，包括运费
            $maxamt = $amt + 105.00; //最大金额
            $nvpstr = "";


            $shopping_about .= "SHIPPINGAMT=$SHIPPINGAMT" . $KD;

            /*
            * Setting up the Shipping address details
            */
            if ($this->userarr['customers_id']) {
                $ADDRESSOVERRIDE = 1;
            } else {
                $ADDRESSOVERRIDE = PAYPAL_EC_ADDRESS; //是否启用PAYPAL的发货地址 1用本站的，0为用PAYPAL的地址
            }
            //echo $ADDRESSOVERRIDE;
            //exit;
            if ($ADDRESSOVERRIDE == 1)
                $shiptoAddress = "&ADDRESSOVERRIDE=$ADDRESSOVERRIDE&SHIPTONAME=$personName&SHIPTOSTREET=$SHIPTOSTREET&SHIPTOCITY=$SHIPTOCITY&SHIPTOSTATE=$SHIPTOSTATE&SHIPTOCOUNTRYCODE=$SHIPTOCOUNTRYCODE&SHIPTOZIP=$SHIPTOZIP";

            $nvpstr = "$shiptoAddress&" . $productall . "MAXAMT=" . (string )$maxamt .
                "&AMT=" . (string )$amt . "&ITEMAMT=" . (string )$itemamt . "&CALLBACKTIMEOUT=4&$shopping_about&ReturnUrl=" .
                $returnURL . "&CANCELURL=" . $cancelURL . "&CURRENCYCODE=" . $currencyCodeType .
                "&PAYMENTACTION=" . $paymentType . "&CUSTOM=" . $CUSTOM . "&INVNUM=" . $INVNUM;
            //echo $nvpstr;
            //exit;
            $nvpstr = $nvpHeader . $nvpstr;

            /* Make the call to PayPal to set the Express Checkout token
            If the API call succeded, then redirect the buyer to PayPal
            to begin to authorize payment.  If an error occured, show the
            resulting errors
            */
            $resArray = $this->hash_call("SetExpressCheckout", $nvpstr);
            $_SESSION['reshash'] = $resArray;
            //print_r($resArray);
            //exit;
            $ack = strtoupper($resArray["ACK"]);

            if ($ack == "SUCCESS") {
                // Redirect to paypal.com here
                $token = urldecode($resArray["TOKEN"]);
                if($type=='EC_Final')
                $useraction='&useraction=commit';
                $payPalURL = PAYPAL_EC_HTTP . $token.$useraction;
                header("Location: " . $payPalURL);
            } else {
                //Redirecting to APIError.php to display errors.
                $location = spUrl('paypal','APIError');//"APIError.html";
                header("Location: $location");
            }
        } else {
            //dump($this->spArgs());
            $token = urlencode($this->spArgs('token'));
            $paypal_step=$this->spArgs('paypal_step');
            
            $nvpstr = "&TOKEN=" . $token;
            $nvpstr = $nvpHeader . $nvpstr;
            $resArray = $this->hash_call("GetExpressCheckoutDetails", $nvpstr);//与PAYPAL-API交互
            
            $_SESSION['reshash'] = $resArray;
            //dump($resArray);
            $ack = strtoupper($resArray["ACK"]);
            $currencyCodeType=$this->spArgs('currencyCodeType');
            foreach($this->currencyarr as $k=>$v)
            {
                if($currencyCodeType==$v[code])
                {
                    $_SESSION['currencies_id']=$k;
                }
            }
           
            foreach ($this->shippingarr as $k => $v) {                
                
                    if ($resArray['SHIPPINGOPTIONNAME'] == $v[3]) {
                        $_SESSION[shipping]=$v[0];
                    }
            }
             
            if ($ack == 'SUCCESS' || $ack == 'SUCCESSWITHWARNING') {
                
                
                $resArray = $_SESSION['reshash'];
                $_SESSION['reshash_check'] = $resArray;
                $_SESSION['paypal_EC']['token'] = $this->spArgs('token');
                $_SESSION['paypal_EC']['payer_id'] = $this->spArgs('PayerID');

                $_SESSION['paypal_EC']['paymentAmount'] = $resArray['ITEMAMT'];
                $_SESSION['paypal_EC']['currCodeType'] = $this->spArgs('currencyCodeType');
                $_SESSION['paypal_EC']['paymentType'] = $this->spArgs('paymentType');
                $_SESSION['payment'] = PAYPAL_EC_CODE;
                $_SESSION['paypal_EC']['SHIPPINGAMT'] = $resArray['SHIPPINGAMT']; //运费
                $_SESSION['paypal_EC']['SHIPPINGCALCULATIONMODE'] = $resArray['SHIPPINGCALCULATIONMODE']; //运费模式
                $_SESSION['paypal_EC']['SHIPPINGOPTIONNAME'] = $resArray['SHIPPINGOPTIONNAME']; //运费名称

                $_SESSION['paypal_EC']['TotalAmount'] = $resArray['AMT'] + $resArray['SHIPDISCAMT'];
                
                //dump($this->spArgs());
                //dump($_SESSION['paypal_EC']);
                //exit;
                $orders_sn = $resArray['INVNUM']; //获取定单号
                $orders_id = $resArray['CUSTOM']; //获取定单ID
                $EMAIL = $resArray['EMAIL']; //付款人EMAIL
                $PAYERID = $resArray['PAYERID']; //付款人ID
                $FIRSTNAME = $resArray['FIRSTNAME']; //第1名称
                $LASTNAME = $resArray['LASTNAME']; //第2名称
                $COUNTRYCODE = $resArray['COUNTRYCODE']; //国家代码us
                $SHIPTONAME = $resArray['SHIPTONAME']; //客户全名
                $SHIPTOSTREET = $resArray['SHIPTOSTREET']; //街道
                $SHIPTOCITY = $resArray['SHIPTOCITY']; //城市
                $SHIPTOSTATE = $resArray['SHIPTOSTATE']; //省市
                $SHIPTOZIP = $resArray['SHIPTOZIP']; //邮编
                $SHIPTOCOUNTRYCODE = $resArray['SHIPTOCOUNTRYCODE']; //国家代码us
                $SHIPTOCOUNTRYNAME = $resArray['SHIPTOCOUNTRYNAME']; //国家全称United States
                $CURRENCYCODE = $resArray['CURRENCYCODE']; //币种
                $AMT = $resArray['AMT']; //总价
                $ITEMAMT = $resArray['ITEMAMT']; //商品小计
                $TAXAMT = $resArray['TAXAMT']; //税
                $SHIPPINGOPTIONAMOUNT = $resArray['SHIPPINGOPTIONAMOUNT']; //运费
                $SHIPPINGCALCULATIONMODE = $resArray['SHIPPINGCALCULATIONMODE']; //运费模式
                $SHIPPINGOPTIONNAME = $resArray['SHIPPINGOPTIONNAME']; //运费名称
                $comments=$resArray['PAYMENTREQUEST_0_NOTETEXT'];//评论
                $_SESSION['comments']=$comments;
                $firstname = $FIRSTNAME;
                $lastname = $LASTNAME;
                $fullname = $SHIPTONAME;
                $street_address = $SHIPTOSTREET;
                $suburb = '';
                $city = $SHIPTOCITY;
                $state = $SHIPTOSTATE;
                $postcode = $SHIPTOZIP;
                $zone_country_id = $this->forcount($SHIPTOCOUNTRYCODE, 4, 2);
                $zone_country=$SHIPTOCOUNTRYNAME;
                $telephone = '';
                $email_address = $EMAIL;
                
//                                foreach ($resArray as $key => $value) {
//                
//                                    echo "$key:$value<br>";
//                                }
//                                exit;

                $conditions = array("orders_sn" => $orders_sn);
                $orderobj = spClass('orderModel');
                $customersobj = spClass("customersModel");
                //判断订单是否存在
                $order = $orderobj->find($conditions);
                //echo 'asdfa1';
                if ($order) {
                    //echo 'asdfa2';
                    //再判断用户是否登入
                    if ($this->userarr['customers_id']) {
                        $clienturl = spUrl('main','CheckoutPayment');
                        //这里直接结束付款
                        
                        if($paypal_step=='Order_Complete'){//这里是通过直接付款返回页面
                            $return=$this->DoExpressCheckoutPayment($_SESSION['paypal_EC']['token'],$orders_sn,$orders_id);
                            if($return)
                            $this->jump(spUrl('main','CheckoutSuccess')); 
                        }
                        $_SESSION['payment_step']='checkout_payment';
                        
                    } else {
                        //没登入，判断用户是否存在，不存在就新建一个用户
                        $customers = $customersobj->find(array('customers_email_address' => $email_address));
                        //dump($customers);
                        //exit;
                        if ($customers == null) {
                            //不存在，下面新建一个用户

                            $password = generate_rand(10);
                            $data_customers = array('customers_firstname' => $firstname,
                                'customers_lastname' => $lastname, 'customers_email_address' => $email_address,
                                'customers_telephone' => $telephone, 'customers_pass' => $password,
                                'no_customers' => 1, 'customers_adddate' => time(), 'customers_lastlogin' =>
                                time());
                            $data_address = array('customers_firstname' => $firstname, 'customers_lastname' =>
                                $lastname, 'entry_street_address' => $street_address, 'entry_suburb' => $suburb,
                                'entry_postcode' => $postcode, 'entry_city' => $city, 'entry_state' => $state,
                                'entry_country_id' => $zone_country_id);

                            $customerstype = $customersobj->create_account($data_customers, $data_address);

                            if ($_SESSION['HB']) //如果临时购物车转正成功
                                {
                                    $this->clear_session();
                                $clienturl = spUrl('main','ShoppingCart');
                            } else { //否则跳到第3步
                                $_SESSION['payment_step']='checkout_payment';
                                $clienturl = spUrl('main','CheckoutPayment');
                            }

                        } else {
                            //用户名存在，就登入合并购物车
                            $loginok = $customersobj->loingok($email_address);
                            if ($loginok)
                                $customersobj->CartHB();
                            if ($_SESSION['HB']) //如果存在合并就跳到购物车
                                {
                                $this->clear_session();
                                $clienturl = spUrl('main','ShoppingCart');
                            } else { //否则跳到第3步
                                $_SESSION['payment_step']='checkout_payment';
                                $clienturl = spUrl('main','CheckoutPayment');
                            }
                            //echo $clienturl;
                            //exit;
                        }
                    }
                    $customers = spClass('customersSession')->read();//从SEESSION表中获取当前用户信息
                    $customers = unserialize($customers);//反序例化
                    $customers[detail]=spClass('address_bookModel')->return_address($customers[customers_default_address_id]);
                    //dump($customers);
                    //exit;
                    if(PAYPAL_EC_ADDRESS==1){
                        $firstname = $customers[detail][customers_firstname];
                        $lastname = $customers[detail][customers_lastname];
                        $fullname = $customers[detail][customers_name];
                        $street_address = $customers[detail][entry_street_address];
                        $suburb = $customers[detail][entry_suburb];
                        $city = $customers[detail][entry_city];
                        $state = $customers[detail][entry_state];
                        $postcode = $customers[detail][entry_postcode];
                        $zone_country=$this->forcount($customers[detail][entry_country_id], 1, 1);
                        $telephone = $customers[customers_telephone];
                        $email_address = $customers[customers_email_address];
                    }
                    $fullname = ($fullname<>'')?$fullname:$customers[detail][customers_firstname].' '.$customers[detail][customers_lastname];
                    //dump($customers);
                    //exit;
                    //存在就修改订单数据
                    $verified = 1;
                    $order_date = date("l dS \of F Y h:i:s A", time());
                    $data = array(
                    'customers_id' => $customers['customers_id'],
                     'customers_name' => $fullname,
                        'customers_street_address' =>$street_address <> '' ? $street_address : '0',
                        
                        'customers_city' => $city,
                        'customers_postcode' => $postcode, 
                        'customers_state' => $state,
                        'customers_country' => $zone_country, 
                        'customers_telephone' => $telephone,
                        'customers_email_address' => $email_address,
                        
                        'delivery_name' => $fullname,
                        'delivery_street_address' => $street_address,
                        'delivery_city' => $city,
                        'delivery_postcode' => $postcode, 
                        'delivery_state' => $state,
                        'delivery_country' => $zone_country, 
                        
                        'billing_name' => $fullname, 
                        'billing_street_address' => $street_address,                         
                        'billing_city' => $city,
                        'billing_postcode' => $postcode, 
                        'billing_state' => $state,
                        'billing_country' => $zone_country, 
                        'orders_status' => $verified,
                        'rppay_id' => $TRANSACTIONID, 
                        'last_modified' => $order_date
                        );
                       
                    $orderobj->update($conditions, $data);
                    $this->jump($clienturl);
                }
            } else {
                //Redirecting to APIError.php to display errors.
                $location = spUrl('paypal','APIError');//"APIError.html";
                header("Location: $location");
            }
        }
        //echo $this->hash_call();
    }
    
    
    
    public function DoExpressCheckoutPayment($token,$orders_sn,$orders_id)
    {
                if($token==''){
                    $token=$_SESSION['paypal_EC']['token'];
                    $orders_sn=$_SESSION['orders_sn'];
                    $orders_id=$_SESSION['orders_id'];
                }
                if($token=='')
                $this->jump(spUrl('main','ShoppingCart'));
                
                ini_set('session.bug_compat_42', 0);
                ini_set('session.bug_compat_warn', 0);
                
                
                $SHIPPINGAMT=$this->SHIPPINGAMT;
                //收集资料，作最后确认收款
                $token = urlencode($token);
                //dump($this->total);
                $paymentAmount = Get_price_abc(array('price'=>$this->total[price1]*$this->code2['value'],'price2'=>$this->total[price2]*$this->code2['value']));
                $paymentAmount = $paymentAmount + $SHIPPINGAMT*$this->code2['value'];
                $paymentAmount = urlencode($paymentAmount);
                $paymentType = urlencode($_SESSION['paypal_EC']['paymentType']);
                $currCodeType = urlencode($this->code2[code]);
                $payerID = urlencode($_SESSION['paypal_EC']['payer_id']);
                $serverName = urlencode($_SERVER['paypal_EC']['SERVER_NAME']);

                $nvpstr = '&TOKEN=' . $token . '&PAYERID=' . $payerID . '&PAYMENTACTION=' . $paymentType .
                    '&AMT=' . $paymentAmount . '&CURRENCYCODE=' . $currCodeType . '&IPADDRESS=' . $serverName;
                //echo $nvpstr;
                $resArray = $this->hash_call("DoExpressCheckoutPayment", $nvpstr);
                
                $resArray_check=$_SESSION['reshash_check'];
                if($resArray_check['PAYMENTREQUEST_0_NOTETEXT']<>'')
                $comments2="Comments:".$resArray_check['PAYMENTREQUEST_0_NOTETEXT']."<br/>";//评论
                $SHIPPINGCALCULATIONMODE=$resArray_check[SHIPPINGCALCULATIONMODE];
                $shipping_module_code=$resArray_check[SHIPPINGOPTIONNAME];
                $shipping_method=$resArray_check[SHIPPINGOPTIONAMOUNT];
                $order_total=$resArray_check[ITEMAMT];
                $ack = strtoupper($resArray["ACK"]);
                $paymentType=$resArray[PAYMENTTYPE];
                $ordertime=$resArray[ORDERTIME];
                $PAYMENTSTATUS=$resArray[PAYMENTSTATUS];
                $CURRENCYCODE = $resArray['CURRENCYCODE']; //币种
                $AMT = $resArray['AMT']; //总价
                //判断是否付款成功，不成功就显示错误信息
                
                if ($ack != 'SUCCESS' && $ack != 'SUCCESSWITHWARNING') {
                    $_SESSION['reshash'] = $resArray;
                    $location = spUrl('paypal','APIError');//"APIError.html";
                    header("Location: $location");
                } else {
                    $_SESSION['orders_id']='';
                    $_SESSION['orders_sn']='';
                    
                    $verified=2;
                    //$this->jump('checkout_success.html');
                    $TRANSACTIONID = $resArray['TRANSACTIONID']; //PAYPAL交易号
                    //下面开始修改订单状态，并发送订单邮件
//                                                 foreach($resArray_check as $key => $value) {
//                    
//                        			                 echo "$key:$value<br>";
//                        			             }
//                                                 foreach($resArray as $key => $value) {
//                    
//                        			                 echo "$key:$value<br>";
//                        			             }
//                                                 exit;
                    
                    $order_date=date("l dS \of F Y h:i:s A",time());
                    //订单状态
                    $conditions = "orders_sn='".$orders_sn."'";
                    $data_order=array('shipping_module_code'=>$shipping_module_code,'shipping_method'=>$shipping_method,'last_modified'=>$order_date,'orders_status'=>$verified,'rppay_id'=>$TRANSACTIONID);
                    //spClass('orderModel')->update_order($data_order,$orders_sn);
                    spClass('orderModel')->update($conditions,$data_order);
                    
                   //exit;
                    //订单的交易过程
                    $comments = $comments2.'Transaction ID:'.$TRANSACTIONID.'- Order_sn:'.$orders_sn.'<br/>Payment Type:PayPal Express Checkout ('.$paymentType.') <br/>Timestamp:'.$ordertime.'<br/>Payment Status:'.$PAYMENTSTATUS.'<br/> Currency:' . $CURRENCYCODE . '-Amount:' . $AMT;
                    $data2 = array('orders_sn' => $orders_sn, 'orders_status_id' => $verified,'comments' => $comments, 'date_added' => $order_date);
                    spClass('orders_status_historyModel')->Create($data2);
                    
                    //如果为支付成功就删除购物车
    
                    $customers_basket = spClass('customers_basketModel');
                    $customers_id = $this->userarr['customers_id']; //此数据来自初始化
                    $conditions2 = array('customers_id' => $customers_id);
                    $customers_basket->delete($conditions2); // 删除记录
                    
                    //这里将放置付款成功提醒邮件
                    $ordermail = spClass('email_templateModel')->order_send($orders_sn); //发送订单邮件
                    $this->clear_session();  
  
                //echo $token.'-'.$orders_sn.'-'.$orders_id;
                
                //require_once "GetExpressCheckoutDetails.php";
                return true;
            }
    }
    /**
     * 错误提示并记录
     */
    function APIError()
    {

        $resArray = $_SESSION['reshash'];
        if (isset($_SESSION['curl_error_no'])) {
            $errorCode = $_SESSION['curl_error_no'];
            $errorMessage = $_SESSION['curl_error_msg'];

            echo 'Error Number:' . $errorCode . '<br/>';
            echo 'Error Message:' . $errorMessage . '<br/>';
        } else {
            foreach ($resArray as $key => $value) {

                $msg.= "$key:$value "."\n";
            }
        }
        $this->paypallog($msg);
        echo $msg;   
    }
    
    function nvpHeader()
    {
        $API_Endpoint = $this->API_Endpoint;
        $version = $this->version;
        $API_UserName = $this->API_UserName;
        $API_Password = $this->API_Password;
        $API_Signature = $this->API_Signature;
        $nvp_Header = $this->nvp_Header;
        $subject = $this->subject;
        $AUTH_token = $this->AUTH_token;
        $AUTH_signature = $this->AUTH_signature;
        $AUTH_timestamp = $this->AUTH_timestamp;
        $nvpHeaderStr = "";
        if (defined('AUTH_MODE')) {
            //$AuthMode = "3TOKEN"; //Merchant's API 3-TOKEN Credential is required to make API Call.
            //$AuthMode = "FIRSTPARTY"; //Only merchant Email is required to make EC Calls.
            //$AuthMode = "THIRDPARTY";Partner's API Credential and Merchant Email as Subject are required.
            $AuthMode = "AUTH_MODE";
        } else {

            if ((!empty($API_UserName)) && (!empty($API_Password)) && (!empty($API_Signature)) &&
                (!empty($subject))) {
                $AuthMode = "THIRDPARTY";
            } else
                if ((!empty($API_UserName)) && (!empty($API_Password)) && (!empty($API_Signature))) {
                    $AuthMode = "3TOKEN";
                } elseif (!empty($AUTH_token) && !empty($AUTH_signature) && !empty($AUTH_timestamp)) {
                    $AuthMode = "PERMISSION";
                } elseif (!empty($subject)) {
                    $AuthMode = "FIRSTPARTY";
                }
        }
        switch ($AuthMode) {

            case "3TOKEN":
                $nvpHeaderStr = "&PWD=" . urlencode($API_Password) . "&USER=" . urlencode($API_UserName) .
                    "&SIGNATURE=" . urlencode($API_Signature);
                break;
            case "FIRSTPARTY":
                $nvpHeaderStr = "&SUBJECT=" . urlencode($subject);
                break;
            case "THIRDPARTY":
                $nvpHeaderStr = "&PWD=" . urlencode($API_Password) . "&USER=" . urlencode($API_UserName) .
                    "&SIGNATURE=" . urlencode($API_Signature) . "&SUBJECT=" . urlencode($subject);
                break;
            case "PERMISSION":
                $nvpHeaderStr = $this->formAutorization($AUTH_token, $AUTH_signature, $AUTH_timestamp);
                break;
        }
        return $nvpHeaderStr;
    }

    /**
     * hash_call: Function to perform the API call to PayPal using API signature
     * @methodName is name of API  method.
     * @nvpStr is nvp string.
     * returns an associtive array containing the response from the server.
     */


    function hash_call($methodName, $nvpStr)
    {
        //declaring of global variables
        $API_Endpoint = $this->API_Endpoint;
        $version = $this->version;
        $API_UserName = $this->API_UserName;
        $API_Password = $this->API_Password;
        $API_Signature = $this->API_Signature;
        $nvp_Header = $this->nvp_Header;
        $subject = $this->subject;
        $AUTH_token = $this->AUTH_token;
        $AUTH_signature = $this->AUTH_signature;
        $AUTH_timestamp = $this->AUTH_timestamp;
        // form header string
        $API_Endpoint = $this->API_Endpoint;

        $nvpheader = $this->nvpHeader();
        //setting the curl parameters.
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $API_Endpoint);

        curl_setopt($ch, CURLOPT_VERBOSE, 1);

        //turning off the server and peer verification(TrustManager Concept).
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);

        //in case of permission APIs send headers as HTTPheders
        if (!empty($AUTH_token) && !empty($AUTH_signature) && !empty($AUTH_timestamp)) {
            $headers_array[] = "X-PP-AUTHORIZATION: " . $nvpheader;

            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers_array);
            curl_setopt($ch, CURLOPT_HEADER, false);
        } else {
            $nvpStr = $nvpheader . $nvpStr;
        }
        //if USE_PROXY constant set to TRUE in Constants.php, then only proxy will be enabled.
        //Set proxy name to PROXY_HOST and port number to PROXY_PORT in constants.php
        if (USE_PROXY)
            curl_setopt($ch, CURLOPT_PROXY, PROXY_HOST . ":" . PROXY_PORT);

        //check if version is included in $nvpStr else include the version.
        if (strlen(str_replace('VERSION=', '', strtoupper($nvpStr))) == strlen($nvpStr)) {
            $nvpStr = "&VERSION=" . urlencode($version) . $nvpStr;
        }

        $nvpreq = "METHOD=" . urlencode($methodName) . $nvpStr;

        //setting the nvpreq as POST FIELD to curl
        curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);

        //getting response from server
        $response = curl_exec($ch);

        //convrting NVPResponse to an Associative Array
        $nvpResArray = $this->deformatNVP($response);
        $nvpReqArray = $this->deformatNVP($nvpreq);
        //dump($nvpResArray);
        //exit;
        $_SESSION['nvpReqArray'] = $nvpReqArray;

        if (curl_errno($ch)) {
            // moving to display page to display curl errors
            $_SESSION['curl_error_no'] = curl_errno($ch);
            $_SESSION['curl_error_msg'] = curl_error($ch);
            $location = spUrl('paypal','APIError');//"APIError.html";
            header("Location: $location");
        } else {
            //closing the curl
            curl_close($ch);
        }

        return $nvpResArray;
    }

    /** This function will take NVPString and convert it to an Associative Array and it will decode the response.
     * It is usefull to search for a particular key and displaying arrays.
     * @nvpstr is NVPString.
     * @nvpArray is Associative Array.
     */

    function deformatNVP($nvpstr)
    {

        $intial = 0;
        $nvpArray = array();


        while (strlen($nvpstr)) {
            //postion of Key
            $keypos = strpos($nvpstr, '=');
            //position of value
            $valuepos = strpos($nvpstr, '&') ? strpos($nvpstr, '&') : strlen($nvpstr);

            /*getting the Key and Value values and storing in a Associative Array*/
            $keyval = substr($nvpstr, $intial, $keypos);
            $valval = substr($nvpstr, $keypos + 1, $valuepos - $keypos - 1);
            //decoding the respose
            $nvpArray[urldecode($keyval)] = urldecode($valval);
            $nvpstr = substr($nvpstr, $valuepos + 1, strlen($nvpstr));
        }
        return $nvpArray;
    }
    function formAutorization($auth_token, $auth_signature, $auth_timestamp)
    {
        $authString = "token=" . $auth_token . ",signature=" . $auth_signature .
            ",timestamp=" . $auth_timestamp;
        return $authString;
    }


    public function return_paypal()
    {
        dump($this->spArgs());
    }

    public function pdtpaypal()
    {
        //dump($this->spArgs());
        //获取 PayPal 交易流水号 tx
        $tx_token = $this->spArgs(txn_id);
        //定义您的身份标记
        $auth_token = PAYPAL_SIGNATURE;
        //形成验证字符串
        $req = " cmd=_notify-synch&tx=$tx_token&at=$auth_token";
        //将交易流水号及身份标记返回 PayPal 验证
        $header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
        $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
        $header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
        $fp = fsockopen(PAYPAL_HTTP, 80, $errno, $errstr, 30);
        if (!$fp) { // HTTP ERROR
            echo "HTTP ERROR";
        } else {
            fputs($fp, $header . $req); //获取返回数据
            $res = '';
            echo $fp;
            $headerdone = false;
            while (!feof($fp)) {
                $line = fgets($fp, 1024);
                if (strcmp($line, "\r\n") == 0) { //获取头
                    $headerdone = true;
                } else
                    if ($headerdone) { //获取主体内容
                        $res .= $line;
                    }
            } //解析获取内容
            $lines = explode("\n", $res);
            //dump($lines);
            $keyarray = array();
            if (strcmp($lines[0], "SUCCESS") == 0) {
                for ($i = 1; $i < count($lines); $i++) {
                    list($key, $val) = explode("=", $lines[$i]);
                    $keyarray[urldecode($key)] = urldecode($val);
                }

                //检查交易付款状态 payment_status 是否为 „Completed‟
                //检查交易流水号 txn_id 是否已经被处理过
                //检查接收 EMAIL receiver_email 是否为您的 PayPal 中已经注册的 EMAIL
                //检查金额 mc_gross 是否正确
                //……
                //处理此次付款明细
                //该付款明细所有变量可参考：
                //https://www.paypal.com/IntegrationCenter/ic_ipn-pdt-variable-reference.html
                $name = $keyarray['first_name'] . ' ' . $keyarray['last_name'];
                $itemname = $keyarray['item_name'];
                $amount = $keyarray['mc_gross'];
                echo ("<p><h3>Thank you for you purchase!</h3></p>");
                echo ("<b>Payment Details:</b><br>\n");
                echo ("<li>Name: $name</li>\n");
                echo ("<li>Item: $itemname</li>\n");
                echo ("<li>Amount: $amount</li>\n");
            } else
                if (strcmp($lines[0], "FAIL") == 0) {
                    //获取付款明细失败，记录并检查
                    
                }
        }
        fclose($fp);
        echo "Your transaction has been completed, and a receipt for your purchase hasbeen emailed to your.<br>You may log into your account at<a href=‟https://www.paypal.com‟> www.paypal.com</a>to view.";
    }

    public function ipn_paypal()
    {
        //从 PayPal 出读取 POST 信息同时添加变量„cmd‟
        $req = 'cmd=_notify-validate';
        foreach ($_POST as $key => $value) {
            $value = urlencode(stripslashes($value));
            $req .= "&$key=$value";
        }
        //建议在此将接受到的信息记录到日志文件中以确认是否收到 IPN 信息
        //将信息 POST 回给 PayPal 进行验证
        $header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
        $header .= "Content-Type:application/x-www-form-urlencoded\r\n";
        $header .= "Content-Length:" . strlen($req) . "\r\n\r\n";
        //在 Sandbox 情况下，设置：
        //$fp = fsockopen('www.sandbox.paypal.com', 80,$errno,$errstr,30);
        $fp = fsockopen(PAYPAL_HTTP, 80, $errno, $errstr, 30);
        //将 POST 变量记录在本地变量中
        //该付款明细所有变量可参考：
        //https://www.paypal.com/IntegrationCenter/ic_ipn-pdt-variable-reference.html
        dump($this->spArgs());
        $item_name = $_POST['item_name'];
        $item_number = $_POST['item_number'];
        $payment_status = $_POST['payment_status'];
        $payment_amount = $_POST['mc_gross'];
        $payment_currency = $_POST['mc_currency'];
        $txn_id = $_POST['txn_id'];
        $receiver_email = $_POST['receiver_email'];
        $payer_email = $_POST['payer_email'];
        //…
        //判断回复 POST 是否创建成功
        if (!$fp) { //HTTP 错误
        } else {
            //将回复 POST 信息写入 SOCKET 端口
            fputs($fp, $header . $req); //开始接受 PayPal 对回复 POST 信息的认证信息
            while (!feof($fp)) {
                $res = fgets($fp, 1024); //已经通过认证
                if (strcmp($res, "VERIFIED") == 0) { //检查付款状态
                    //检查 txn_id 是否已经处理过
                    //检查 receiver_email 是否是您的 PayPal 账户中的 EMAIL 地址
                    //检查付款金额和货币单位是否正确
                    //处理这次付款，包括写数据库
                } else
                    if (strcmp($res, "INVALID") == 0) { //未通过认证，有可能是编码错误或非法的 POST 信息
                    }
            }
            fclose($fp);
        }

    }
}
